﻿using System;
using System.IO;
using System.Collections;
using System.Linq;
using System.Text;

namespace imeem.api.util
{
	public class Util
	{
		public static string GetMD5Hash(string input)
		{
			System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
			byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
			bytes = md5.ComputeHash(bytes);
			System.Text.StringBuilder builder = new System.Text.StringBuilder();
			
			foreach (byte b in bytes)
			{
				builder.Append(b.ToString("x2").ToLower());
			}
			
			return builder.ToString();
		}
		
		public static string GenerateSignature(string methodName, Hashtable parameters, string apiSecret)
		{
			ArrayList args = new ArrayList(parameters.Keys);
			args.Sort();
			StringBuilder builder = new StringBuilder();
			builder.Append(methodName);
			
			foreach (string arg in args)
			{
				string keyValue = string.Format("{0}={1}", arg, parameters[arg]);
				builder.Append(keyValue);
			}
			
			builder.Append(apiSecret);
			return Util.GetMD5Hash(builder.ToString());
		}
		
		private static string formDataParameterFieldFormat = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
		private static string formDataFileFieldFormat = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
		private static string formEndOfPostFieldFormat = "--{0}--\r\n";
		
		public static byte[] GeneratePostBodyBytes(ArrayList postParameters, string boundry)
		{
			MemoryStream postDataStream = new MemoryStream();
			BinaryWriter postDataWriter = new BinaryWriter(postDataStream);
			
			foreach (PostParameter postParameter in postParameters)
			{
				switch (postParameter.Type)
				{
					case PostParameterType.File:
						{
							FileStream fileStream = null;
							
							try
							{
								fileStream = File.OpenRead(postParameter.Value as string);
								byte[] fileData = new byte[fileStream.Length];
								fileStream.Read(fileData, 0, fileData.Length);
								string fileParameter = string.Format(formDataFileFieldFormat, boundry, postParameter.Name, postParameter.Filename, "application/octet-stream");
								postDataWriter.Write(Encoding.UTF8.GetBytes(fileParameter));
								postDataWriter.Write(fileData);
								postDataWriter.Write(Encoding.UTF8.GetBytes("\r\n"));
							}
							catch (Exception ex)
							{
								//Left Empty
							}
							finally
							{
								if (fileStream != null)
								{
									fileStream.Close();
								}
							}
							break;
						}
					case PostParameterType.Parameter:
					default:
						{
							string parameter = string.Format(formDataParameterFieldFormat, boundry, postParameter.Name, postParameter.Value);
							postDataWriter.Write(Encoding.UTF8.GetBytes(parameter));
							break;
						}
				}
			}
			
			postDataWriter.Write(Encoding.UTF8.GetBytes(string.Format(formEndOfPostFieldFormat, boundry)));
			postDataWriter.Flush();
			byte[] messagePostData = postDataStream.ToArray();
			postDataStream.Close();
			postDataWriter.Close();
			
			return messagePostData;
		}
		
	}
}


